home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
libs
/
knowhow4
/
sview.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-10
|
13KB
|
485 lines
#include "sview.h"
char* firstString(int first, char* string)
{
char* str = string;
for(int i = 0; i < first && str != NULL; i++)
{
str = strchr(str, '\n');
if(str != NULL)
str++;
}
return str;
}
///////////////////////////
ScrollView::ScrollView(loc start_pos, char* str, rect b, loc sc, int interv,
int dir)
{
bnd = b;
start = loc(0, 0); pos = start_pos; string = str;
number_of_nl = nRet(string);
scale = sc; interval = interv; direction = dir;
findString = NULL;
}
///////////////////////////
void ScrollView::showCursor()
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
int sz;
int size_y = interval
* (sz = fnt->scaledtextsize("H!", scale.X, scale.Y).height())
/ 10 * pos.Y; // vertical position
int sh = (interval - 10) / 2 * sz / 10;
char* tmp = firstString(pos.Y + start.Y - 1, string); // the n-th string
tmp += start.X; // visible part of tmp
int size_x; // HP text width, pixels
char* tmp1 = new char[pos.X + 1]; // temporary length
strncpy(tmp1, tmp, pos.X - 1);
tmp1[pos.X - 1] = '\0'; // 0-terminated string
size_x = fnt->scaledtextsize(tmp1, scale.X, scale.Y).width();
delete tmp1;
moveto(size_x, size_y - sh);
setwritemode(XOR_PUT);
setlinestyle(SOLID_LINE, 1, 1);
lineto(size_x, size_y - sh - sz);
setwritemode(COPY_PUT);
setviewport(0, 0, getmaxx(), getmaxy(), 1);
curs = loc(size_x, size_y);
}
/////////////////////////
int ScrollView::lineLen(int num)
{
char* str1 = firstString(num, string);
char* str2 = firstString(1, str1);
if(str2 == NULL)
return strlen(str1);
return str2 - str1;
/* char* c = new char[str2 - str1 + 1];
strncpy(c, str1, str2 - str1);
c[str2 - str1] = '\0'; // 0-terminated string
int l = strlen(c);
delete c;
return l;
*/ }
/////////////////////////
char* ScrollView::showString(char* str, loc scale,
int mode)
{
char* s = strchr(str, '\n');
if(s != NULL)
{
int new_pos = s - str;
char c = str[new_pos];
str[new_pos] = '\0';
if(new_pos > start.X)
drawscaledstr(*fnt, str + start.X, scale.X,
scale.Y, mode, direction);
str[new_pos] = c;
return str + new_pos + 1;
}
if(strlen(str) > start.X)
drawscaledstr(*fnt, str + start.X, scale.X,
scale.Y, mode, direction);
return NULL;
}
/////////////////////////
void ScrollView::show(int first, int last, int mode, int shift)
{
char* str = firstString(first - 1, string);
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
int s_size = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
int top = (first - start.Y - 1) * s_size;
int sh = (interval - 10) / 2
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
if(first != last || shift > 0)
curs.X = 0;
else
str += pos.X + shift - 1;
struct viewporttype viewinfo;
getviewsettings(&viewinfo);
if(curs.X == 0)
{
setviewport(viewinfo.left - 3, viewinfo.top,
viewinfo.right + 3, viewinfo.bottom, 1);
}
bar(curs.X, top, viewinfo.right - viewinfo.left + 7,
top + s_size * (last - first + 1));
setviewport(viewinfo.left, viewinfo.top, viewinfo.right,
viewinfo.bottom, 1);
moveto(curs.X, top - sh + s_size);
for(int i = first; i <= last; i++)
{
if((str = showString(str, scale, mode)) == NULL)
break;
moveto(0, s_size * (i - start.Y + 1) - sh);
}
setviewport(0, 0, getmaxx(), getmaxy(), 1);
}
//////////////////////////
int ScrollView::up(int jmp)
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
int ret = 1;
hideCursor();
int h = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
int view_h = bnd.height() / h;
if(pos.Y > jmp)
{
pos.Y -= jmp;
int len;
if(len = lineLen(pos.Y + start.Y - 1) < pos.X + start.X)
{
pos.X = 1; start.X = len - 1;
show(start.Y + 1, start.Y + bnd.height() / h);
}
}
else
{
if((start.Y > jmp - 1) || (start.Y > view_h - 1))
{
if(start.Y > view_h - 1)
{
start.Y -= view_h;
pos.Y = view_h - jmp + 1;
}
else // if(start.Y > jmp - 1)
{
pos.Y = start.Y - jmp + 1;
start.Y = 0;
}
int len = lineLen(pos.Y + start.Y - 1);
if(len < pos.X + start.X)
{
pos.X = 1; start.X = len - 1;
}
show(start.Y + 1, start.Y + 1 + bnd.height() / h);
}
else
ret = 0;
}
showCursor();
setviewport(0, 0, getmaxx(), getmaxy(), 1);
return ret;
}
/////////////////////////////////
int ScrollView::dn(int jmp)
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
int ret = 1;
hideCursor();
int h = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
int view_h = bnd.height() / h;
if(pos.Y + jmp - 2 < view_h && start.Y + pos.Y + jmp - 2 < number_of_nl)
{
pos.Y += jmp;
int len = lineLen(start.Y + pos.Y - 1);
if(len < pos.X + start.X)
{
pos.X = 1; start.X = len ? len - 1 : 0;
show(start.Y + 1, start.Y + 1 + bnd.height() / h);
}
}
else
{
if((start.Y + view_h - 2 < number_of_nl)
|| (start.Y + pos.Y + jmp - 2 < number_of_nl))
{
if(start.Y + view_h - 2 < number_of_nl)
{
start.Y += view_h;
pos.Y = 1;
}
else // if(start.Y + pos.Y + jmp - 1 < number_of_nl)
{
start.Y += jmp;
}
int len;
if(len = lineLen(start.Y + pos.Y - 1) < pos.X + start.X)
{
pos.X = 1; start.X = len - 1;
}
show(start.Y + 1, start.Y + 1 + bnd.height() / h);
}
else
ret = 0;
}
showCursor();
setviewport(0, 0, getmaxx(), getmaxy(), 1);
return ret;
}
/////////////////////////////////
int ScrollView::left(int jmp)
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
int ret = 0;
hideCursor();
if(pos.X > jmp) // not leftmost position
pos.X -= jmp;
else // leftmost screen position
{
if(start.X > jmp - 1)
{
ret = 1;
start.X -= jmp;
int h = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
show(start.Y + 1, start.Y + 1 + bnd.height() / h);
}
}
showCursor();
setviewport(0, 0, getmaxx(), getmaxy(), 1);
return ret;
}
////////////////////////
char* ScrollView::getLine(int n)
{
char* str = firstString(n, string);
if(str == NULL)
return NULL;
char* str1;
int len = ((str1 = firstString(1, str)) == NULL) ? strlen(str)
: str1 - str - 1;
char* c = new char[len + 5];
strncpy(c, str, len);
c[len] = '\0'; // 0-terminated string
return c;
}
/////////////////////////
int ScrollView::right(int jmp)
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
int ret = 0;
hideCursor();
char* str = getLine(start.Y + pos.Y - 1); // current line
if(start.X + pos.X + jmp - 2 // if we'll not leave this line
< lineLen(start.Y + pos.Y - 1)) // after this jump
{
str[start.X + pos.X + jmp - 1] = '\0'; // NULL-terminates line
int len = fnt->scaledtextsize(str + start.X, // length of visible
scale.X, scale.Y).width(); // part, pixels
if(bnd.width() > len) // not rightmost position
pos.X += jmp;
else // rightmost screen position
{
ret = 1;
start.X += jmp;
while(fnt->scaledtextsize(str + start.X,
scale.X, scale.Y).width() > bnd.width())
{
start.X++;
pos.X--;
}
int h = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
show(start.Y + 1, start.Y + 1 + bnd.height() / h);
}
}
showCursor();
delete str;
setviewport(0, 0, getmaxx(), getmaxy(), 1);
return ret;
}
////////////////////////
void ScrollView::home()
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
hideCursor();
pos.X = 1;
if(start.X != 0)
{
start.X = 0;
int h = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
show(start.Y + 1, start.Y + 1 + bnd.height() / h);
}
start.X = 0;
showCursor();
setviewport(0, 0, getmaxx(), getmaxy(), 1);
}
////////////////////////
void ScrollView::end()
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
hideCursor();
pos.X = 1;
char* str = getLine(start.Y + pos.Y - 1);
start.X = strlen(str);
int h = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
show(start.Y + 1, start.Y + 1 + bnd.height() / h);
showCursor();
delete str;
setviewport(0, 0, getmaxx(), getmaxy(), 1);
}
////////////////////////
int ScrollView::pgUp()
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
int ret = 1;
hideCursor();
int h = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
h = bnd.height() / h;
if(h < start.Y)
{
start.Y -= h;
pos.Y = 1;
pos.X = 1;
show(start.Y + 1, start.Y + 1 + h);
}
else
ret = 0;
showCursor();
setviewport(0, 0, getmaxx(), getmaxy(), 1);
return ret;
}
/////////////////////////
int ScrollView::pgDn()
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
int ret = 1;
hideCursor();
int h = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
h = bnd.height() / h;
char* str = firstString(start.Y + pos.Y - 1, string);
int returns = nRet(str);
if(h < returns)
{
start.Y += h;
pos.X = 1;
show(start.Y + 1, start.Y + 1 + h);
}
else
ret = 0;
showCursor();
setviewport(0, 0, getmaxx(), getmaxy(), 1);
return ret;
}
/////////////////////////
void ScrollView::toTop()
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
hideCursor();
int h = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
h = bnd.height() / h;
start = loc(0, 0);
pos = loc(1, 1);
show(start.Y + 1, start.Y + 1 + h);
showCursor();
setviewport(0, 0, getmaxx(), getmaxy(), 1);
}
//////////////////////////
void ScrollView::toBottom()
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
hideCursor();
int h = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
h = bnd.height() / h;
start = loc(0, nRet(string));
pos = loc(1, 1);
show(start.Y + 1, start.Y + h + 1);
showCursor();
setviewport(0, 0, getmaxx(), getmaxy(), 1);
}
///////////////////////////
int ScrollView::find(char* search)
{
setviewport(bnd.origin.X, bnd.origin.Y,
bnd.corner.X, bnd.corner.Y, 1);
int ret = 0; // find or not
hideCursor();
char* str = firstString(start.Y + pos.Y - 1, string); // start search position
char* fnd = strstr(str + 1, search); // first
if(fnd != NULL) // if search string
{ // presents
int h = interval
* fnt->scaledtextsize("H!", scale.X, scale.Y).height() / 10;
h = bnd.height() / h; // screen height, in HP intervals
int y_pos = nRet(string) - nRet(fnd) + 1; // y pos of find string
if(start.Y + h >= y_pos) // do not redraw screen
pos.Y = y_pos - start.Y;
else // redraw screen
{
start.Y = y_pos - 1;
pos.Y = 1;
}
char* work = getLine(y_pos - 1); // line containing str
char* work1 = firstString(y_pos - 1, string); // part of string
int x_pos = fnd - work1; // distance from line beginning
if(x_pos <= start.X) // redraw screen
{
start.X = x_pos;
pos.X = 1;
}
else
{
work[x_pos] = '\0';
if(fnt->scaledtextsize(work + start.X, scale.X, scale.Y).width()
>= bnd.width()) // we are not in bnd
{
start.X = x_pos;
pos.X = 1;
}
else // we are in bnd
pos.X = x_pos - start.X;
}
ret = 1;
delete work;
show(start.Y + 1, start.Y + h + 1);
}
showCursor();
setviewport(0, 0, getmaxx(), getmaxy(), 1);
return ret;
}
/////////////////////////
/*
*/
/////////////////////////